import json
from typing import List, Dict, Any, Optional
import re


class EventParser:
    """
    面向对象的解析器，用于处理Intel处理器性能监控事件的JSON文件
    支持解析sapphirerapids_core.json、sapphirerapids_uncore.json等格式的文件
    """

    def __init__(self, file_path: str):
        """
        初始化解析器并加载JSON文件

        Args:
            file_path: JSON文件的路径
        """
        self.file_path = file_path
        self._header: Dict[str, Any] = {}
        self._events: List[Dict[str, Any]] = []
        self._load_file()

    def _load_file(self) -> None:
        """加载并解析JSON文件"""
        try:
            with open(self.file_path, "r", encoding="utf-8") as f:
                data = json.load(f)
                self._header = data.get("Header", {})
                self._events = data.get("Events", [])
        except json.JSONDecodeError as e:
            raise ValueError(f"JSON解析错误: {e}")
        except FileNotFoundError:
            raise FileNotFoundError(f"文件不存在: {self.file_path}")

    @property
    def header(self) -> Dict[str, Any]:
        """
        获取文件的Header信息

        Returns:
            包含Header信息的字典
        """
        return self._header.copy()

    @property
    def events(self) -> List[Dict[str, Any]]:
        """
        获取所有事件列表

        Returns:
            事件对象的列表
        """
        return self._events.copy()

    @property
    def event_count(self) -> int:
        """
        获取事件总数

        Returns:
            事件数量
        """
        return len(self._events)

    def get_event_by_name(self, event_name: str) -> Optional[Dict[str, Any]]:
        """
        根据事件名称查找事件

        Args:
            event_name: 要查找的事件名称

        Returns:
            找到的事件对象，如果没有找到则返回None
        """
        for event in self._events:
            if event.get("EventName") == event_name:
                return event.copy()
        return None

    def get_events_by_unit(self, unit: str) -> List[Dict[str, Any]]:
        """
        根据Unit类型筛选事件

        Args:
            unit: 要筛选的Unit类型，如'PCU'、'UBOX'等

        Returns:
            符合条件的事件列表
        """
        return [event.copy() for event in self._events if event.get("Unit") == unit]

    def get_events_by_event_code(self, event_code: str) -> List[Dict[str, Any]]:
        """
        根据EventCode筛选事件

        Args:
            event_code: 要筛选的EventCode，如'0x01'

        Returns:
            符合条件的事件列表
        """
        return [
            event.copy()
            for event in self._events
            if event.get("EventCode") == event_code
        ]

    def search_events(
        self, search_term: str, search_fields: Optional[List[str]] = None
    ) -> List[Dict[str, Any]]:
        """
        搜索事件中的关键字

        Args:
            search_term: 搜索的关键字
            search_fields: 要搜索的字段列表，如果为None则搜索所有字段

        Returns:
            包含关键字的事件列表
        """
        results = []
        search_term_lower = search_term.lower()

        for event in self._events:
            match = False

            if search_fields:
                for field in search_fields:
                    if (
                        field in event
                        and isinstance(event[field], str)
                        and search_term_lower in event[field].lower()
                    ):
                        match = True
                        break
            else:
                for value in event.values():
                    if isinstance(value, str) and search_term_lower in value.lower():
                        match = True
                        break

            if match:
                results.append(event.copy())

        return results

    def get_unique_units(self) -> List[str]:
        """
        获取所有唯一的Unit类型

        Returns:
            唯一Unit类型的列表
        """
        units = set()
        for event in self._events:
            if "Unit" in event:
                units.add(event["Unit"])
        return sorted(list(units))

    def to_dict(self) -> Dict[str, Any]:
        """
        将解析后的数据转换回字典格式

        Returns:
            包含Header和Events的字典
        """
        return {"Header": self._header, "Events": self._events}


class SapphireRapidsEventParser(EventParser):
    """
    专门用于解析Sapphire Rapids处理器事件的解析器
    继承自EventParser，添加了特定于Sapphire Rapids的功能
    """

    def get_core_events(self) -> List[Dict[str, Any]]:
        """
        获取核心事件（不包含Unit字段或Unit为特定值的事件）

        Returns:
            核心事件列表
        """
        return [event.copy() for event in self._events if "Unit" not in event]

    def get_uncore_events(self) -> List[Dict[str, Any]]:
        """
        获取非核心事件（包含Unit字段的事件）

        Returns:
            非核心事件列表
        """
        return [event.copy() for event in self._events if "Unit" in event]

    def get_events_by_counter(self, counter: str) -> List[Dict[str, Any]]:
        """
        根据Counter字段筛选事件

        Args:
            counter: 要筛选的计数器，如'0,1,2,3'或'Fixed counter 0'

        Returns:
            符合条件的事件列表
        """
        return [
            event.copy() for event in self._events if event.get("Counter") == counter
        ]

    def get_non_deprecated_events(self) -> List[Dict[str, Any]]:
        """
        获取非弃用的事件

        Returns:
            非弃用事件列表
        """
        return [
            event.copy()
            for event in self._events
            if event.get("Deprecated", "0") == "0"
        ]

    def get_precise_events(self) -> List[Dict[str, Any]]:
        """
        获取精确事件（Precise为1的事件）

        Returns:
            精确事件列表
        """
        return [event.copy() for event in self._events if event.get("Precise") == "1"]


class MetricParser:
    """
    面向对象的解析器，用于处理Intel处理器性能监控指标的JSON文件
    支持解析sapphirerapidshbm_metrics_perf.json等格式的文件
    """

    def __init__(self, file_path: str):
        """
        初始化解析器并加载JSON文件

        Args:
            file_path: JSON文件的路径
        """
        self.file_path = file_path
        self._metrics: List[Dict[str, Any]] = []
        self._load_file()

    def _load_file(self) -> None:
        """加载并解析JSON文件"""
        try:
            with open(self.file_path, "r", encoding="utf-8") as f:
                data = json.load(f)
                # metrics文件直接是一个数组
                self._metrics = data if isinstance(data, list) else []
        except json.JSONDecodeError as e:
            raise ValueError(f"JSON解析错误: {e}")
        except FileNotFoundError:
            raise FileNotFoundError(f"文件不存在: {self.file_path}")

    @property
    def metrics(self) -> List[Dict[str, Any]]:
        """
        获取所有指标列表

        Returns:
            指标对象的列表
        """
        return self._metrics.copy()

    @property
    def metric_count(self) -> int:
        """
        获取指标总数

        Returns:
            指标数量
        """
        return len(self._metrics)

    def get_metric_by_name(self, metric_name: str) -> Optional[Dict[str, Any]]:
        """
        根据指标名称查找指标

        Args:
            metric_name: 要查找的指标名称

        Returns:
            找到的指标对象，如果没有找到则返回None
        """
        for metric in self._metrics:
            if metric.get("MetricName") == metric_name:
                return metric.copy()
        return None

    def get_metrics_by_group(self, metric_group: str) -> List[Dict[str, Any]]:
        """
        根据MetricGroup筛选指标

        Args:
            metric_group: 要筛选的指标组

        Returns:
            符合条件的指标列表
        """
        return [
            metric.copy()
            for metric in self._metrics
            if metric.get("MetricGroup") == metric_group
        ]

    def search_metrics(
        self, search_term: str, search_fields: Optional[List[str]] = None
    ) -> List[Dict[str, Any]]:
        """
        搜索指标中的关键字

        Args:
            search_term: 搜索的关键字
            search_fields: 要搜索的字段列表，如果为None则搜索所有字段

        Returns:
            包含关键字的指标列表
        """
        results = []
        search_term_lower = search_term.lower()

        for metric in self._metrics:
            match = False

            if search_fields:
                for field in search_fields:
                    if (
                        field in metric
                        and isinstance(metric[field], str)
                        and search_term_lower in metric[field].lower()
                    ):
                        match = True
                        break
            else:
                for value in metric.values():
                    if isinstance(value, str) and search_term_lower in value.lower():
                        match = True
                        break

            if match:
                results.append(metric.copy())

        return results

    def get_unique_metric_groups(self) -> List[str]:
        """
        获取所有唯一的MetricGroup

        Returns:
            唯一MetricGroup的列表
        """
        groups = set()
        for metric in self._metrics:
            if "MetricGroup" in metric:
                groups.add(metric["MetricGroup"])
        return sorted(list(groups))

    def get_unique_scale_units(self) -> List[str]:
        """
        获取所有唯一的ScaleUnit

        Returns:
            唯一ScaleUnit的列表
        """
        units = set()
        for metric in self._metrics:
            if "ScaleUnit" in metric:
                units.add(metric["ScaleUnit"])
        return sorted(list(units))

    def extract_events_from_expression(self, metric_name: str) -> List[str]:
        """
        从指标表达式中提取事件名称

        Args:
            metric_name: 指标名称

        Returns:
            从表达式中提取的事件名称列表
        """
        metric = self.get_metric_by_name(metric_name)
        if not metric or "MetricExpr" not in metric:
            return []

        # 使用正则表达式提取事件名称（假设事件名称格式为大写字母和点的组合）
        # 这是一个简化的模式，可能需要根据实际情况调整
        events = re.findall(r"[A-Z_]+\.[A-Z_]+", metric["MetricExpr"])
        # 也提取没有点的简单事件名称
        simple_events = re.findall(r"\b[A-Z_]+\b(?![(\./])", metric["MetricExpr"])
        # 合并并去重
        all_events = list(set(events + simple_events))

        # 过滤掉可能不是事件名称的关键字
        keywords_to_filter = ["CPU", "SYSTEM", "TSC", "FREQ"]
        filtered_events = [
            event for event in all_events if event not in keywords_to_filter
        ]

        return filtered_events


class SapphireRapidsMetricParser(MetricParser):
    """
    专门用于解析Sapphire Rapids处理器指标的解析器
    继承自MetricParser，添加了特定于Sapphire Rapids的功能
    """

    def get_perf_metrics(self) -> List[Dict[str, Any]]:
        """
        获取与性能相关的指标

        Returns:
            性能指标列表
        """
        # 可以根据文件路径或特定关键词来判断
        perf_keywords = ["frequency", "utilization", "cpi", "cycles", "instructions"]
        return [
            metric.copy()
            for metric in self._metrics
            if any(
                keyword in metric.get("MetricName", "").lower()
                for keyword in perf_keywords
            )
        ]

    def get_cache_metrics(self) -> List[Dict[str, Any]]:
        """
        获取与缓存相关的指标

        Returns:
            缓存指标列表
        """
        cache_keywords = ["l1", "l2", "l3", "cache", "hit", "miss"]
        return [
            metric.copy()
            for metric in self._metrics
            if any(
                keyword in metric.get("MetricName", "").lower()
                or keyword in metric.get("BriefDescription", "").lower()
                for keyword in cache_keywords
            )
        ]

    def get_memory_metrics(self) -> List[Dict[str, Any]]:
        """
        获取与内存相关的指标

        Returns:
            内存指标列表
        """
        memory_keywords = ["mem", "memory", "load", "store", " bandwidth"]
        return [
            metric.copy()
            for metric in self._metrics
            if any(
                keyword in metric.get("MetricName", "").lower()
                or keyword in metric.get("BriefDescription", "").lower()
                for keyword in memory_keywords
            )
        ]

    def get_metrics_by_scale_unit(self, scale_unit: str) -> List[Dict[str, Any]]:
        """
        根据ScaleUnit筛选指标

        Args:
            scale_unit: 要筛选的单位，如'1GHz'、'100%'

        Returns:
            符合条件的指标列表
        """
        return [
            metric.copy()
            for metric in self._metrics
            if metric.get("ScaleUnit") == scale_unit
        ]


# 示例使用方法
if __name__ == "__main__":
    import sys

    if len(sys.argv) > 1:
        file_path = sys.argv[1]
        # 根据文件扩展名或路径判断使用哪个解析器
        if "metric" in file_path.lower():
            # 使用指标解析器
            try:
                parser = SapphireRapidsMetricParser(file_path)
                print(f"文件: {file_path}")
                print(f"指标总数: {parser.metric_count}")

                # 打印唯一的MetricGroup
                groups = parser.get_unique_metric_groups()
                print(f"唯一的MetricGroup ({len(groups)}):")
                for group in groups:
                    if group:  # 跳过空组
                        print(f"  - {group}")

                # 打印唯一的ScaleUnit
                units = parser.get_unique_scale_units()
                print(f"唯一的ScaleUnit ({len(units)}):")
                for unit in units:
                    print(f"  - {unit}")

                # 搜索特定指标
                search_term = "cpu"
                search_results = parser.search_metrics(search_term)
                print(f"\n包含'{search_term}'的指标 ({len(search_results)}):")
                for metric in search_results[:3]:  # 只显示前3个结果
                    print(
                        f"  - {metric.get('MetricName')}: {metric.get('BriefDescription')}"
                    )
                    print(f"    表达式: {metric.get('MetricExpr')}")

                # 提取表达式中的事件名称
                if search_results:
                    first_metric_name = search_results[0].get("MetricName")
                    events = parser.extract_events_from_expression(first_metric_name)
                    print(f"\n从'{first_metric_name}'表达式中提取的事件:")
                    for event in events:
                        print(f"  - {event}")

            except Exception as e:
                print(f"错误: {e}")
        else:
            # 使用事件解析器
            try:
                parser = SapphireRapidsEventParser(file_path)
                print(f"文件: {file_path}")
                print(f"版本: {parser.header.get('Version')}")
                print(f"发布日期: {parser.header.get('DatePublished')}")
                print(f"事件总数: {parser.event_count}")

                # 打印唯一的Unit类型
                units = parser.get_unique_units()
                print(f"唯一的Unit类型 ({len(units)}):")
                for unit in units:
                    print(f"  - {unit}")

                # 搜索特定事件
                search_term = "CLOCK"
                search_results = parser.search_events(search_term)
                print(f"\n包含'{search_term}'的事件 ({len(search_results)}):")
                for event in search_results[:3]:  # 只显示前3个结果
                    print(
                        f"  - {event.get('EventName')}: {event.get('BriefDescription')}"
                    )

            except Exception as e:
                print(f"错误: {e}")
    else:
        # 默认使用示例路径
        print("请提供要解析的文件路径。")
        print("示例:")
        print(
            f"  python {sys.argv[0]} /home/xyjiang/project/zenmpx/data/spr/SPR/events/sapphirerapids_uncore.json"
        )
        print(
            f"  python {sys.argv[0]} /home/xyjiang/project/zenmpx/data/spr/SPR/metrics/perf/sapphirerapidshbm_metrics_perf.json"
        )
